#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <termios.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyUSB0"
#define R_BUF_LEN (256)

void printtid(void);
void* com_read(void* pstatu)
{
  printtid();
  int i=0;
  int fd,c=0,num;
  struct termios oldtio,newtio;
  char buf[R_BUF_LEN];
  printf("start...\n");
  /*打开PC机的COM1通信端口*/ 
  fd=open(MODEMDEVICE,O_RDWR | O_NOCTTY | O_NONBLOCK/*| O_NDELAY*/);
  if(fd<0)
  {
    perror(MODEMDEVICE);
    exit(1);
  }
  printf("open ...\n");
  /*将目前终端机的结构保存至oldtio结构*/ 
  tcgetattr(fd,&oldtio);
  /*清除newtio结构，重新设置通信协议*/
  bzero(&newtio,sizeof(newtio));
  /*通信协议设为8N1,8位数据位,N没有效验,1位结束位*/
  newtio.c_cflag = BAUDRATE |CS8|CLOCAL|CREAD;  
  newtio.c_iflag = IGNPAR;  
  newtio.c_oflag = 0;
  /*设置为正规模式*/
  newtio.c_lflag=ICANON;
  /*清除所有队列在串口的输入*/ 
  tcflush(fd,TCIFLUSH);   /*新的termios的结构作为通信端口的参数*/
  tcsetattr(fd,TCSANOW,&newtio);
  printf("reading...\n");
  while(*(int*)pstatu)
  {
     num = read(fd,buf, R_BUF_LEN);
     buf[R_BUF_LEN-1] = 0;
     if(num > 0 && num <= R_BUF_LEN)
     {
       buf[num]=0;  
       printf("%s", buf);  
       fflush(stdout);
     }
  }
  printf("close...\n");
  close(fd);
  /*恢复旧的通信端口参数*/ 
  tcsetattr(fd,TCSANOW,&oldtio);
}

void *com_send(void *p)
{
  printtid();
  int fd,c=0;
  struct termios oldtio,newtio;
  char ch;
  static char s1[20];
  printf("Start...\n ");
  /*打开arm平台的COM1通信端口*/ 
  fd=open(MODEMDEVICE,O_RDWR | O_NOCTTY);
  if(fd<0)  
  {  
    perror(MODEMDEVICE);  
    exit(1);  
  }
  printf(" Open...\n "); 
  /*将目前终端机的结构保存至oldtio结构*/
  tcgetattr(fd,&oldtio);
  /*清除newtio结构，重新设置通信协议*/
  bzero(&newtio,sizeof(newtio));
  /*通信协议设为8N1*/
  newtio.c_cflag =BAUDRATE |CS8|CLOCAL|CREAD; //波特率 8个数据位 本地连接 接受使能  
  newtio.c_iflag=IGNPAR;                      //忽略奇偶校验错误  
  newtio.c_oflag=0;
  /*设置为正规模式*/
  newtio.c_lflag=ICANON;                     //规范输入
  /*清除所有队列在串口的输出*/
  tcflush(fd,TCOFLUSH);
  /*新的termios的结构作为通信端口的参数*/
  tcsetattr(fd,TCSANOW,&newtio);
  printf("Writing...\n ");
  while(*(char*)p != 0)
  {
     int res = 0;
     res = write(fd,(char*)p, 1);
     if(res != 1) printf("send %c error\n", *(char*)p);
     else printf("send %c ok\n", *(char*)p);
     ++p;
  }
  printf("Close...\n");
  close(fd);
  /*还原旧的通信端口参数*/
  tcsetattr(fd,TCSANOW,&oldtio); 
  printf("leave send thread\n");
}

/* 
    开始线程 
    thread_fun  线程函数 
    pthread     线程函数所在pthread变量 
    par     线程函数参数 
    COM_STATU   线程函数状态控制变量 1:运行 0:退出 
*/  
int start_thread_func(void*(*func)(void*), pthread_t* pthread, void* par, int* COM_STATU)
{
  *COM_STATU = 1;
  memset(pthread, 0, sizeof(pthread_t));
  int temp;
  /*创建线程*/
  if((temp = pthread_create(pthread, NULL, func, par)) != 0) 
    printf("线程创建失败!\n");
  else
  {
    int id=pthread_self();
    printf("线程%u被创建\n", *pthread);
  }   
  return temp;
}

/* 
    结束线程 
    pthread     线程函数所在pthread变量 
    COM_STATU   线程函数状态控制变量 1:运行 0:退出 
*/ 
int stop_thread_func(pthread_t* pthread, int* COM_STATU)
{
  printf("prepare stop thread %u\n", *pthread);
  *COM_STATU = 0;
  if(*pthread !=0)
  {
     pthread_join(*pthread, NULL);
  }
  printf("线程%d退出!\n", *COM_STATU);
}

void printtid(void)
{
  int id = pthread_self();
  printf("in thread %u\n", id);
}

int main()
{
  pthread_t thread[2];
  printtid();
  const int READ_THREAD_ID = 0;
  const int SEND_THREAD_ID = 1;
  int COM_READ_STATU = 0;
  int COM_SEND_STATU = 0;
  if(start_thread_func(com_read, &thread[READ_THREAD_ID],  &COM_READ_STATU, &COM_READ_STATU) != 0)  
  {  
    printf("error to leave\n");  
    return -1;  
  }
  printf("wait 3 sec\n");
  sleep(3);
  printf("wake after 3 sec\n");    
  if(start_thread_func(com_send, &thread[SEND_THREAD_ID], "ABCDEFGHIJKLMNOPQRST", &COM_SEND_STATU) != 0)  
  {  
    printf("error to leave\n");  
    return -1;  
  }
  printtid();
  printf("wait 10 sec\n");
  sleep(10);
  printf("wake after 10 sec\n");
  stop_thread_func(&thread[READ_THREAD_ID], &COM_READ_STATU);
  stop_thread_func(&thread[SEND_THREAD_ID], &COM_SEND_STATU);
  return 0;
}
